"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

"""
"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 开启按需回放参数进行备2节点stop操作后，主节点进行failover操作
Create At   : 2024-04-07
Owner       : zhenjinyang
Description :
    1、查看集群状态; expect:集群状态正常
    2、加载ondemand参数; expect:执行成功
    3、重启; expect:执行成功
    4、检验参数; expect:执行成功
    5、备1节点执行stop; expect:执行成功
    6、再次查看切换后集群状态 expect:集群状态正常,备1切换为主节点，原主节点降为备节点
    7、主节点进行failover
    8、ondemand参数回复初始状态; expect:执行成功
    9、集群停止; expect:执行成功
    10、原节点进行节点启动; expect:执行成功
    11、参数为初始状态; expect:成功
    12、恢复环境为初始集群状态; expect:成功
Expect      :
    1、集群状态正常
    2、加载ondemand参数成功
    3、重启执行成
    4、检验参数执行成功
    5、备1节点执行stop执行成功
    6、集群状态正常,备1切换为主节点，原主节点降为备节点
    7、主节点进行failover
    8、ondemand参数回复初始状态
    9、集群停止执行成功
    10、原节点进行节点启动执行成功
    11、参数为初始状态
    12、恢复环境为初始集群状态
History     :
    1、2024-04-07 创建
"""
import os
import unittest
import time
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')
Standby1_SH = CommonSH('Standby1DbUser')

@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()

        self.s1_comsh = CommonSH('Standby1DbUser')
        self.s2_comsh = CommonSH('Standby2DbUser')
        self.common = Common('Standby1DbUser')
        self.recovery_parse_workers = 'recovery_parse_workers'
        self.recovery_redo_workers = 'recovery_redo_workers'
        self.hot_standby = 'hot_standby'
        self.ss_enable_ondemand_recovery = 'ss_enable_ondemand_recovery'
        self.ss_ondemand_recovery_mem_size = 'ss_ondemand_recovery_mem_size'

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        if "cluster_state   : Normal" in status:
            self.log.info(status + "集群状态正常")
        else:
            stopdn = Primary_SH.exec_cm_ctl('stop')
            self.log.info(stopdn)
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            startdn = Primary_SH.exec_cm_ctl('start')
            self.log.info(startdn)
            self.assertIn(self.constant.cm_start_success_msg, startdn,
                    '拉起集群失败')
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            self.log.info(status)

        self.recovery_parse_workers_default = self.common.show_param(self.recovery_parse_workers)
        self.recovery_redo_workers_default = self.common.show_param(self.recovery_redo_workers)
        self.hot_standby_default = self.common.show_param(self.hot_standby)
        self.ss_enable_ondemand_recovery_default = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.ss_ondemand_recovery_mem_size_default = self.common.show_param(self.ss_ondemand_recovery_mem_size)


    def test_shared_storage(self):
        text = '-----step1:查看集群状态; expect:集群状态正常-----'
        self.log.info(text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step2:加载ondemand参数; expect:执行成功-----'
        self.log.info(text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_parse_workers}=2')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_redo_workers}=2')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.hot_standby}=off')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_enable_ondemand_recovery}=on')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_ondemand_recovery_mem_size}=5GB')
        self.assertTrue(result, '执行失败' + text)

        text = '-----step3:重启; expect:执行成功-----'
        self.log.info(text)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        text = '-----step4:检验参数; expect:执行成功-----'
        self.log.info(text)
        result_param = self.common.show_param(self.recovery_parse_workers)
        self.assertEquals(result_param, '2', '执行失败' + text)
        result_param = self.common.show_param(self.recovery_redo_workers)
        self.assertEquals(result_param, '2', '执行失败' + text)
        result_param = self.common.show_param(self.hot_standby)
        self.assertEquals(result_param, 'off', '执行失败' + text)
        result_param = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.assertEquals(result_param, 'on', '执行失败' + text)
        result_param = self.common.show_param(self.ss_ondemand_recovery_mem_size)
        self.assertEquals(result_param, '5GB', '执行失败' + text)

        text = '-----step5:节点2 stop; expect:成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_cm_ctl(mode='stop',
                                           param='-n 2',
                                           path=f'-D {macro.DB_INSTANCE_PATH}')
        self.log.info(stopdn)
        self.assertIn("stop instance successfully", stopdn,
                '停止dn节点失败')

        text = '-----step6:查看集群状态; expect:集群状态Degraded-----'
        self.log.info(text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Degraded', status, '执行失败' + text)

        text = '-----step7:节点1 failover; expect:成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_failover()
        self.log.info(stopdn)
        time.sleep(50)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        res3 = status.splitlines()[-1].split('|')[2].split('6003')[-1]
        self.log.info(status)
        self.assertIn('P Down    Manually stopped', res1, '执行失败' + text)
        self.assertTrue('S Down    Manually stopped' in res2,
                '执行失败' + text)
        self.assertTrue('S Primary Normal' in res3 or 'S Standby Normal' in res3,
                '执行失败' + text)

        text = '-----step8:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')

        text = '-----step9:查看集群状态; expect:状态正常-----'
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn('P Standby Normal ', res1, '执行失败' + text)

        text = '-----step10:ondemand参数回复初始状态; expect:执行成功-----'
        self.log.info(text)

        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_parse_workers}={self.recovery_parse_workers_default}')
        self.assertTrue(result, '执行失败' + text)
        self.log.info(text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.recovery_redo_workers}={self.recovery_redo_workers_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.hot_standby}={self.hot_standby_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_enable_ondemand_recovery}={self.ss_enable_ondemand_recovery_default}')
        self.assertTrue(result, '执行失败' + text)
        result = self.s1_comsh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.ss_ondemand_recovery_mem_size}={self.ss_ondemand_recovery_mem_size_default}')
        self.assertTrue(result, '执行失败' + text)

        text = '-----step11:集群停止; expect:执行成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn,
                '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn("Maybe cm_server is not running, or timeout expired. Please try again.", res1, '执行失败' + text)

        text = '-----step12:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step13:参数为初始状态; expect:成功-----'
        result_param = self.common.show_param(self.recovery_parse_workers)
        self.assertEquals(result_param, self.recovery_parse_workers_default, '执行失败' + text)
        result_param = self.common.show_param(self.recovery_redo_workers)
        self.assertEquals(result_param, self.recovery_redo_workers_default, '执行失败' + text)
        result_param = self.common.show_param(self.hot_standby)
        self.assertEquals(result_param, self.hot_standby_default, '执行失败' + text)
        result_param = self.common.show_param(self.ss_enable_ondemand_recovery)
        self.assertEquals(result_param, self.ss_enable_ondemand_recovery_default, '执行失败' + text)
        result_param = self.common.show_param(self.ss_ondemand_recovery_mem_size)
        self.assertEquals(result_param, self.ss_ondemand_recovery_mem_size_default, '执行失败' + text)

    def tearDown(self):
        text = '-----step14:集群重启; expect:执行成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)

        text = '-----step15:恢复环境为初始集群状态; expect:成功-----'
        self.log.info(text)

        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn,
                '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)

        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cvipd')
        self.log.info(status)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                    status.splitlines()[-1].split('|')[2].split('6003')[-1],
                    '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')